# -*- coding: UTF-8 -*-
import cv2
import math
import numpy as np
import pytesseract

def isbadline(p1, p2):
    len2 = (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2
    if len2 < 400:
        return True
    else:
        return False


def isline(p1, p2, p3):
    #反向直线
    if p1[0] == p3[0] and p1[1] == p3[1]:
        return 2 
    len13 = math.sqrt((p1[0] - p3[0]) ** 2 + (p1[1] - p3[1]) ** 2)

    if len13 < 5:
        return 2 
    len12 = math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
    len23 = math.sqrt((p2[0] - p3[0]) ** 2 + (p2[1] - p3[1]) ** 2)

    ca = math.fabs(len12 + len23 - len13)
    print "ca=", p1, p2, p3, ca
    if ca < 5:
        return 1 #顺序直线
    else:
        return 0


def computeIntersect(a, b):
    x1, y1, x2, y2 = a[0], a[1], a[2], a[3]
    x3, y3, x4, y4 = b[0], b[1], b[2], b[3]
    d = ((x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4))
    if d:
        x = ((x1 * y2 - y1 * x2) * (x3 - x4) -
             (x1 - x2) * (x3 * y4 - y3 * x4)) / d
        y = ((x1 * y2 - y1 * x2) * (y3 - y4) -
             (y1 - y2) * (x3 * y4 - y3 * x4)) / d
        return [x, y]
    else:
        return [-1, -1]

def pstolines(ps):
    lines = []
    for i in range(0, len(ps)):
        j = i + 1
        if j == len(ps):
            j = 0
        if not isbadline(ps[i], ps[j]):
            lines.append([ps[i, 0], ps[i, 1], ps[j, 0], ps[j, 1]])
    return lines;      

#返回的是封闭的
def removebadline(lines):
    for i in range(0, len(lines)):
        j = i + 1
        if j == len(lines):
            j = 0
        if (lines[i][2] != lines[j][0]) or (lines[i][3] != lines[j][1]):
            temp = computeIntersect(lines[i], lines[j])
            lines[i][2] = abs(temp[0])
            lines[j][0] = abs(temp[0])
            lines[i][3] = abs(temp[1])
            lines[j][1] = abs(temp[1])

    return lines  



def removemoreline(lines,wise):
    #fclock=False
    while 1:
        linecopy = []
        headp=0
        for i in range(0, len(lines)):
            j = i + 1
            if j == len(lines):
                j = 0
            temp=isline(lines[i][:2], lines[i][2:], lines[j][2:])
            if temp==1:
                lines[j][0] = lines[i][0]
                lines[j][1] = lines[i][1]
            elif temp==2:
                if headp==0:
                    headp=j
                    linecopy=[]
                else:
                    linecopy.append(lines[i])
                    wise[0]= not wise[0]
                    print "wise=",wise
                    break
            else:
                linecopy.append(lines[i])
        print "linecopy=", linecopy
        if len(lines) == len(linecopy):
            break
        lines = linecopy
    return lines

def hulllines(lines):
    ppt=[]
    for i in range(0, len(lines)):
        ppt.append([lines[i][0],lines[i][1]])
    if lines[0][0]!=lines[len(lines)-1][0] or lines[0][1]!=lines[len(lines)-1][0] :
        ppt.append([lines[len(lines)-1][0],lines[len(lines)-1][1]])
    hull=cv2.convexHull(np.array(ppt),clockwise=5)
    print "hull1=",hull
    hull=hull.reshape(len(hull),2)
    for i in range(0,len(hull)):
        if hull[i][0]<0 : hull[i][0]=-hull[i][0]
        if hull[i][1]<0 : hull[i][1]=-hull[i][1]
    print "hull=",hull
    lines=pstolines(hull)
    lines=removebadline(lines)
    return lines;

def drawlines(shape,lines):
    black = np.zeros(shape, np.uint8)
    for i in range(0, len(lines)):
        cv2.line(black,(lines[i][0], lines[i][1]),(lines[i][2], lines[i][3]),(128),1)    
        cv2.circle(black, (lines[i][0], lines[i][1]), 3, (128), 2)
        cv2.putText(black, str(i), (lines[i][0], lines[i][1]),
                cv2.FONT_HERSHEY_TRIPLEX, 0.4, (255))
    cv2.imshow("9", black)
    cv2.waitKey(0)


src = cv2.imread("./7.png")
#src = cv2.imread("D:/lx/0.jpg")
cv2.imshow("0", src)
src2 = src.copy()

emptyImage = np.zeros(src.shape, np.uint8)


# 灰度
img = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
black = np.zeros(img.shape, np.uint8)
# 高斯模糊
img = cv2.GaussianBlur(img, (5, 5), 0, 0)
# 膨胀
element = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
img = cv2.dilate(img, element)

# 轮廓
img = cv2.Canny(img, 20, 40, 3)

# 外轮廓
img, contours, hierarchy = cv2.findContours(
    img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)


# 最大面积的外轮廓
max_area = 0
index = 0
for i in range(0, len(contours)):
    ps = contours[i].reshape(len(contours[i]), 2)
    r = cv2.boundingRect(ps)
    # print r
    temparea = r[2] * r[3]
    if temparea > max_area:
        index = i
        max_area = temparea

ct1 = contours[index]


# 轮廓ok ，找四个角点
contours2 = cv2.approxPolyDP(ct1, 3, True)

# 缩减到4个点
# 1.合并线，2.找距离很近的线
lines = []
fclock=[False]
if len(contours2) != 4:

    hull=cv2.convexHull(contours2,clockwise=5)
    #c4 = contours2.reshape(len(contours2), 2)
    c4 = hull.reshape(len(hull), 2)
    lines=pstolines(c4)
    drawlines(img.shape,lines)
    lines=removebadline(lines)
    drawlines(img.shape,lines)
    
    if len(lines) != 4 and len(lines)!=0:
        lines=removemoreline(lines,fclock)
        print "fclock=",fclock
    if len(lines) != 4 and len(lines)!=0:
        fclock=[False]
        lines=hulllines(lines)
        lines=removemoreline(lines,fclock)
    


print fclock




if len(lines) != 4 and len(lines)!=0:
    for i in range(0, len(lines)):
        cv2.circle(black, (lines[i][0], lines[i][1]), 3, (128), 2)
        cv2.line(black,(lines[i][0], lines[i][1]),(lines[i][2], lines[i][3]),(128),1)
        cv2.putText(black, str(i), (lines[i][0], lines[i][1]),
                    cv2.FONT_HERSHEY_TRIPLEX, 0.4, (255))
        cv2.imshow("2",black)

    cv2.circle(black, (lines[len(lines) - 1][0],
                       lines[len(lines) - 1][1]), 3, (128), 2)
    cv2.putText(black, str(len(lines)), (lines[len(lines) - 1][0], lines[len(lines) - 1][1]),
                cv2.FONT_HERSHEY_TRIPLEX, 0.4, (255))


if len(lines) == 4:
    pp1 = []
    for i in range(0, 4):
        j = i + 1
        if j == 4:
            j = 0
        if (lines[i][2] == lines[j][0]) and (lines[i][3] == lines[j][1]):
            pp1.append([lines[i][2], lines[i][3]])
        else:
            # 求交叉点
            temp = computeIntersect(lines[i], lines[j])
            pp1.append(temp)
    contours2 = np.array(pp1)




cv2.waitKey(0)

height = 0
width = 0
if len(contours2) == 4:
    c4 = contours2.reshape(4, 2)
    if fclock[0] :
        print "c4=",c4
        c4list=c4.tolist()
        c4list.reverse()
        c4=np.array(c4list)
        print "逆时针c4=",c4





    c5 = np.zeros((4, 2), dtype=np.float32)
    
    minx=99999
    minindex=0
    for i in range(0,len(c4)) :
        temp=c4[i,0]**2+c4[i,1]**2
        if minx>temp :
            minx=temp
            minindex=i
    for i in range(0,4) :
        c5[i]=c4[minindex]
        minindex=minindex+1
        if minindex==4:
            minindex=0


    height = math.sqrt((c5[0, 0] - c5[1, 0])**2 + (c5[0, 1] - c5[1, 1])**2)
    height1 = math.sqrt((c5[2, 0] - c5[3, 0])**2 + (c5[2, 1] - c5[3, 1])**2)
    if height < height1:
        height = height1
    width = math.sqrt((c5[0, 0] - c5[3, 0])**2 + (c5[0, 1] - c5[3, 1])**2)
    width1 = math.sqrt((c5[2, 0] - c5[1, 0])**2 + (c5[2, 1] - c5[1, 1])**2)
    if width < width1:
        width = width1

    c2 = np.zeros((4, 2), dtype=np.float32)

    c2[1] = [0, height]
    c2[2] = [width, height]
    c2[3] = [width, 0]
    c2[0] = [0, 0]

 
    transmtx = cv2.getPerspectiveTransform(c5, c2)
    newim = np.zeros((np.int0(width), np.int0(height), 3), np.uint8)
    newim = cv2.warpPerspective(
        src, transmtx, (np.int0(width), np.int0(height)), newim)

    cv2.imshow("5", newim)
    black = np.zeros(img.shape, np.uint8)
    for i in range(0, 4):
        cv2.circle(black, (c5[i, 0], c5[i, 1]), 3, (128), 2)
        cv2.circle(black, (c2[i, 0], c2[i, 1]), 3, (255), 2)
        cv2.putText(black, str(i), (c5[i, 0], c5[i, 1]),
                    cv2.FONT_HERSHEY_TRIPLEX, 0.8, (128))
        cv2.putText(black, str(i), (c2[i, 0], c2[i, 1]),
                    cv2.FONT_HERSHEY_TRIPLEX, 0.8, (255))
    #cv2.imshow("3", black)
    cv2.imshow("4", src)
    #print(pytesseract.image_to_string(src,lang="chi_sim"))


    #print(pytesseract.image_to_string(newim,lang="chi_sim"))

cv2.waitKey(0)
cv2.destroyAllWindows()
